<template>
  <div class="category-tree">
    <el-card class="tree-card">
      <template #header>
        <div class="card-header">
          <span>分类树形管理</span>
          <div class="header-actions">
            <el-button type="primary" @click="addRootCategory">添加根分类</el-button>
            <el-button @click="expandAll">全部展开</el-button>
            <el-button @click="collapseAll">全部收起</el-button>
          </div>
        </div>
      </template>
      
      <div class="tree-container">
        <el-tree
          ref="treeRef"
          :data="treeData"
          :props="defaultProps"
          node-key="id"
          default-expand-all
          draggable
          @node-drag-end="handleDragEnd"
          @node-click="handleNodeClick"
        >
          <template #default="{ node, data }">
            <div class="tree-node">
              <div class="node-content">
                <el-icon class="node-icon">
                  <Folder v-if="data.children && data.children.length > 0" />
                  <Document v-else />
                </el-icon>
                <span class="node-label">{{ data.name }}</span>
              </div>
              <div class="node-actions">
                <el-button 
                  type="text" 
                  size="small" 
                  @click.stop="addChildCategory(data)"
                >
                  <el-icon><Plus /></el-icon>
                </el-button>
                <el-button 
                  type="text" 
                  size="small" 
                  @click.stop="editCategory(data)"
                >
                  <el-icon><Edit /></el-icon>
                </el-button>
                <el-button 
                  type="text" 
                  size="small" 
                  @click.stop="deleteCategory(data)"
                  :disabled="data.children && data.children.length > 0"
                >
                  <el-icon><Delete /></el-icon>
                </el-button>
              </div>
            </div>
          </template>
        </el-tree>
      </div>
    </el-card>
    
    <!-- 添加/编辑分类对话框 -->
    <el-dialog
      v-model="dialogVisible"
      :title="dialogTitle"
      width="500px"
      @close="resetForm"
    >
      <el-form :model="categoryForm" :rules="rules" ref="formRef" label-width="100px">
        <el-form-item label="分类名称" prop="name">
          <el-input v-model="categoryForm.name" placeholder="请输入分类名称" />
        </el-form-item>
        <el-form-item label="分类编码" prop="code">
          <el-input v-model="categoryForm.code" placeholder="请输入分类编码" />
        </el-form-item>
        <el-form-item label="上级分类" prop="parentId">
          <el-tree-select
            v-model="categoryForm.parentId"
            :data="treeData"
            :props="defaultProps"
            placeholder="请选择上级分类"
            clearable
            check-strictly
          />
        </el-form-item>
        <el-form-item label="排序" prop="sort">
          <el-input-number v-model="categoryForm.sort" :min="0" :max="999" />
        </el-form-item>
        <el-form-item label="描述" prop="description">
          <el-input
            v-model="categoryForm.description"
            type="textarea"
            :rows="3"
            placeholder="请输入分类描述"
          />
        </el-form-item>
      </el-form>
      <template #footer>
        <span class="dialog-footer">
          <el-button @click="dialogVisible = false">取消</el-button>
          <el-button type="primary" @click="submitForm" :loading="submitting">
            确定
          </el-button>
        </span>
      </template>
    </el-dialog>
    
    <!-- 分类详情抽屉 -->
    <el-drawer
      v-model="drawerVisible"
      title="分类详情"
      direction="rtl"
      size="400px"
    >
      <div v-if="selectedCategory" class="category-detail">
        <el-descriptions :column="1" border>
          <el-descriptions-item label="分类名称">
            {{ selectedCategory.name }}
          </el-descriptions-item>
          <el-descriptions-item label="分类编码">
            {{ selectedCategory.code }}
          </el-descriptions-item>
          <el-descriptions-item label="上级分类">
            {{ getParentName(selectedCategory.parentId) }}
          </el-descriptions-item>
          <el-descriptions-item label="创建时间">
            {{ selectedCategory.createTime }}
          </el-descriptions-item>
          <el-descriptions-item label="更新时间">
            {{ selectedCategory.updateTime }}
          </el-descriptions-item>
          <el-descriptions-item label="描述">
            {{ selectedCategory.description || '暂无描述' }}
          </el-descriptions-item>
        </el-descriptions>
        
        <div class="detail-actions">
          <el-button type="primary" @click="editCategory(selectedCategory)">
            编辑分类
          </el-button>
          <el-button @click="addChildCategory(selectedCategory)">
            添加子分类
          </el-button>
        </div>
      </div>
    </el-drawer>
  </div>
</template>

<script setup lang="ts">
import { ref, computed, onMounted } from 'vue'
import { ElMessage, ElMessageBox } from 'element-plus'
import { Folder, Document, Plus, Edit, Delete } from '@element-plus/icons-vue'
import { categoryApi } from '@/api'

const treeRef = ref()
const dialogVisible = ref(false)
const drawerVisible = ref(false)
const submitting = ref(false)
const selectedCategory = ref<any>(null)
const isEdit = ref(false)

// 表单数据
const categoryForm = ref({
  id: '',
  name: '',
  code: '',
  parentId: null,
  sort: 0,
  description: ''
})

// 表单验证规则
const rules = {
  name: [
    { required: true, message: '请输入分类名称', trigger: 'blur' },
    { min: 2, max: 50, message: '长度在 2 到 50 个字符', trigger: 'blur' }
  ],
  code: [
    { required: true, message: '请输入分类编码', trigger: 'blur' },
    { pattern: /^[A-Z0-9_]+$/, message: '编码只能包含大写字母、数字和下划线', trigger: 'blur' }
  ]
}

// 树形数据
const treeData = ref<any[]>([])

// 将扁平列表转换为树形
const buildTree = (list: any[]) => {
  const map: Record<number,string> = {}
  const nodeMap: Record<number, any> = {}
  const roots: any[] = []
  list.forEach((item: any) => {
    const node = {
      ...item,
      name: item.name || item.title || '未命名',
      children: [] as any[]
    }
    nodeMap[item.id] = node
  })
  list.forEach((item: any) => {
    const node = nodeMap[item.id]
    if (item.parentId) {
      const parent = nodeMap[item.parentId]
      if (parent) parent.children.push(node)
      else roots.push(node)
    } else {
      roots.push(node)
    }
  })
  return roots
}

const loadTree = async () => {
  const res: any = await categoryApi.getTree()
  treeData.value = buildTree(res || [])
}

const defaultProps = {
  children: 'children',
  label: 'name',
  value: 'id'
}

const dialogTitle = computed(() => isEdit.value ? '编辑分类' : '添加分类')

const getParentName = (parentId: number | null) => {
  if (!parentId) return '根分类'
  const findParent = (nodes: any[], id: number): string => {
    for (const node of nodes) {
      if (node.id === id) return node.name
      if (node.children) {
        const result = findParent(node.children, id)
        if (result) return result
      }
    }
    return ''
  }
  return findParent(treeData.value, parentId) || '未知'
}

const addRootCategory = () => {
  isEdit.value = false
  categoryForm.value = {
    id: '',
    name: '',
    code: '',
    parentId: null,
    sort: 0,
    description: ''
  }
  dialogVisible.value = true
}

const addChildCategory = (parent: any) => {
  isEdit.value = false
  categoryForm.value = {
    id: '',
    name: '',
    code: '',
    parentId: parent.id,
    sort: 0,
    description: ''
  }
  dialogVisible.value = true
}

const editCategory = (category: any) => {
  isEdit.value = true
  categoryForm.value = { ...category }
  dialogVisible.value = true
}

const deleteCategory = async (category: any) => {
  if (category.children && category.children.length > 0) {
    ElMessage.warning('该分类下有子分类，无法删除')
    return
  }
  
  try {
    await ElMessageBox.confirm(
      `确定要删除分类"${category.name}"吗？`,
      '确认删除',
      {
        confirmButtonText: '确定',
        cancelButtonText: '取消',
        type: 'warning'
      }
    )
    
    await categoryApi.delete(category.id)
    ElMessage.success('删除成功')
    loadTree()
  } catch {
    // 用户取消删除
  }
}

const handleNodeClick = (data: any) => {
  selectedCategory.value = data
  drawerVisible.value = true
}

const handleDragEnd = (draggingNode: any, dropNode: any, dropType: string) => {
  ElMessage.success('拖拽排序成功')
  // 这里应该调用API更新排序
}

const toggleAll = (expand: boolean) => {
  const tree = treeRef.value as any
  if (!tree || !tree.store) return
  const nodesObj = tree.store.nodesMap || tree.store._nodesMap
  if (!nodesObj) return
  Object.values(nodesObj).forEach((node: any) => {
    node.expanded = expand
  })
}

const expandAll = () => {
  toggleAll(true)
}

const collapseAll = () => {
  toggleAll(false)
}

const submitForm = async () => {
  submitting.value = true
  
  try {
    const payload: any = {
      ...categoryForm.value,
      status: 1
    }

    if (isEdit.value) {
      await categoryApi.update(payload.id, payload)
    } else {
      await categoryApi.add(payload)
    }

    ElMessage.success(isEdit.value ? '编辑成功' : '添加成功')
    dialogVisible.value = false
    resetForm()
    loadTree()
  } catch (error) {
    ElMessage.error('操作失败')
  } finally {
    submitting.value = false
  }
}

const resetForm = () => {
  categoryForm.value = {
    id: '',
    name: '',
    code: '',
    parentId: null,
    sort: 0,
    description: ''
  }
}

onMounted(() => {
  loadTree()
})
</script>

<style scoped>
.category-tree {
  padding: 20px;
}

.tree-card {
  max-width: 1200px;
  margin: 0 auto;
}

.card-header {
  display: flex;
  justify-content: space-between;
  align-items: center;
}

.header-actions {
  display: flex;
  gap: 10px;
}

.tree-container {
  min-height: 400px;
}

.tree-node {
  display: flex;
  align-items: center;
  justify-content: space-between;
  width: 100%;
  padding: 5px 0;
}

.node-content {
  display: flex;
  align-items: center;
  gap: 8px;
}

.node-icon {
  color: var(--primary-color);
}

.node-label {
  font-weight: 500;
}

.node-actions {
  display: flex;
  gap: 5px;
  opacity: 0;
  transition: opacity 0.3s;
}

.tree-node:hover .node-actions {
  opacity: 1;
}

.category-detail {
  padding: 20px;
}

.detail-actions {
  margin-top: 20px;
  display: flex;
  gap: 10px;
}

@media (max-width: 768px) {
  .category-tree {
    padding: 10px;
  }
  
  .card-header {
    flex-direction: column;
    gap: 10px;
  }
  
  .header-actions {
    width: 100%;
    justify-content: center;
  }
  
  .node-actions {
    opacity: 1;
  }
}
</style> 